<template>
  <div>
    {{ name }}
  </div>

  <button @click="send">派发</button>

  <div>
    {{ inheritAttrs }}
  </div>

  <div>
    <ul>
      <li v-for="(g, index) in data" :key="index">
        <slot :item="g" :index="index">我是slot插槽</slot>
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts" generic="T">
import { emitChangeFn } from 'element-plus';
import { stringify } from 'postcss';

// 普通方式
// 无法接受泛型
/* defineProps({
  name: {
    type: String,
    required: true
  }
}) */

/* const props = defineProps({
  name: {
    type: Array,
    required: true
  }
})

props.name // 提示unknown[] */


// 方案一
/* import type { PropType } from 'vue'

const props = defineProps({
  name: {
    type: Array as PropType<string[]>, // 泛型
    required: true
  }
})
props.name // 提示string[] */

// 方案二 泛型字面量
/* const props = defineProps<{ 
  name: string[]
}>()
props.name // 提示string[] */

// 方案三 Vue3.3  对defineProps的泛型支持 需要在script标签上加上 generic="T"
// 泛型类型定义
defineProps<{
  name: T[],
  data: T[]
}>()

// emit 普通写法
// const emit = defineEmits(['send'])

// ts写法
/* const emit = defineEmits<{
  (event: string, name: string):void
}>() */

// V3.3 改进  更加精简
const emit = defineEmits<{
  'send': [name: string]
}>()
const send = () => {
  emit('send', 'hello')
}

// Vue3.3 内置了defineOptions 不需要再去下载插件了
/* 
  它里面的属性跟optionsAPI中的属性一样
  常用的属性定义 name xxxxx
  defineProps, defineEmits, 这些都不能在里面声明
*/
defineOptions({
  name: 'xiaopp',
  inheritAttrs: false,
  data() {
    return {
      inheritAttrs: true
    }
  }
})

/* 
  defineSlots 只有声明没有实现  没有任何参数  只能接受ts类型
  约束slot
*/
defineSlots<{
  default(props:{item:T, index:number}):void
}>()
</script>

<style scoped lang='less'>

</style>